import network

from io import led, status_pin
from log import Log
from task import Task

log = Log(tag='Network')

wifi = network.WLAN(network.STA_IF)


class NetworkStatus:
    mac_str = ''

    @staticmethod
    def get_mac():
        if not len(NetworkStatus.mac_str):
            mac = wifi.config('mac')
            for i in mac:
                num_str = hex(i).lstrip('0x')
                if len(num_str) < 2:
                    num_str = '0' + num_str
                NetworkStatus.mac_str += num_str
            NetworkStatus.mac_str = NetworkStatus.mac_str.upper()
            log.debug('Obtain mac: %s' % NetworkStatus.mac_str)
        return NetworkStatus.mac_str

    @staticmethod
    def is_connected():
        return wifi.isconnected()


class WifiWrapper:
    def __init__(self, config):
        self.__ssid_table = config['ap']
        self.__ip = config['ip']
        self.__netmask = config['netmask']
        self.__gateway = config['gateway']
        self.__dns = config['dns']
        self.__dhcp = config['dhcp']

    def connect(self):
        log.debug('Starting Wifi...')
        wifi.active(True)
        while True:
            led.trigger()
            ssid = self.__ssid_table['ssid']
            password = self.__ssid_table['password']
            if password:
                wifi.connect(ssid, password)
                log.info('Try to connect [%s] with password [%s]' % (ssid, password))
            else:
                wifi.connect(ssid)
                log.info('Try to connect [%s] without password' % ssid)
            return

    def inet_setting(self):
        if self.__dhcp:
            log.info('Skip inetSetting(DHCP)')
            return
        log.info('Wifi INet Setting %s %s %s %s' % (self.__ip, self.__netmask, self.__gateway, self.__dns))
        wifi.ifconfig((self.__ip, self.__netmask, self.__gateway, self.__dns))


class WifiConnectTask(Task):
    def __init__(self, wifi_wrapper, on_connect, on_connected):
        self.__wifi_wrapper = wifi_wrapper
        self.__on_connect = on_connect
        self.__on_connected = on_connected

    def setup(self):
        self.__on_connect()
        self.__wifi_wrapper.inet_setting()
        self.__wifi_wrapper.connect()

    def loop(self):
        if NetworkStatus.is_connected():
            log.info('Wifi connected(LOOP)')
            self.__on_connected()
            led.off()
            # deepsleep.sleep()
            return False
        led.trigger()
        return True


class NetworkStatusTask(Task):
    def loop(self):
        if NetworkStatus.is_connected():
            status_pin.ready()
        else:
            status_pin.connecting()
        return True


AP_IP = '192.168.4.1'


class Ap:
    def __init__(self, ssid, password=''):
        self.__ap = network.WLAN(network.AP_IF)
        self.__ssid = ssid
        self.__password = password

    def start(self):
        self.__ap.active(True)
        if self.__password:
            self.__ap.config(essid=self.__ssid, authmode=network.AUTH_WPA_WPA2_PSK, password=self.__password)
        else:
            self.__ap.config(essid=self.__ssid, authmode=network.AUTH_OPEN)
        self.__ap.ifconfig((AP_IP, '255.255.255.0', AP_IP, '8.8.8.8'))
        log.info('WIFI AP IP=[%s]' % AP_IP)
        led.on()

    def stop(self):
        self.__ap.active(False)
        led.off()

